package com.uploader.controller;

import com.uploader.service.FileUploadService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/upload")
@CrossOrigin(origins = "http://localhost:8080")
@Validated
public class FileUploadController {

    private static final Logger logger = LoggerFactory.getLogger(FileUploadController.class);

    @Autowired
    private FileUploadService fileUploadService;

    @Value("${upload.max-chunk-size:5242880}") // 默认5MB
    private long maxChunkSize;

    /**
     * 检查文件是否已存在或部分上传
     */
    @GetMapping("/check")
    public ResponseEntity<?> checkFile(
            @RequestParam @NotBlank(message = "文件哈希不能为空") String fileHash,
            @RequestParam @NotBlank(message = "文件名不能为空") String fileName) {
        try {
            logger.info("检查文件状态: fileHash={}, fileName={}", fileHash, fileName);
            Map<String, Object> result = fileUploadService.checkFile(fileHash, fileName);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            logger.error("检查文件失败: fileHash={}, fileName={}", fileHash, fileName, e);
            return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, "检查文件失败", e.getMessage());
        }
    }

    /**
     * 上传分片
     */
    @PostMapping("/chunk")
    public ResponseEntity<?> uploadChunk(
            @RequestParam("file") @NotNull(message = "上传文件不能为空") MultipartFile file,
            @RequestParam("fileHash") @NotBlank(message = "文件哈希不能为空") String fileHash,
            @RequestParam("chunk") int chunk) {
        try {
            // 验证分片大小
            if (file.getSize() > maxChunkSize) {
                return buildErrorResponse(HttpStatus.BAD_REQUEST, "分片大小超过限制", 
                        String.format("最大分片大小: %d bytes, 当前大小: %d bytes", maxChunkSize, file.getSize()));
            }

            logger.info("开始上传分片: fileHash={}, chunk={}, size={} bytes", 
                    fileHash, chunk, file.getSize());
            
            fileUploadService.uploadChunk(file, fileHash, chunk);
            
            logger.info("分片上传成功: fileHash={}, chunk={}", fileHash, chunk);
            return ResponseEntity.ok().body(buildSuccessResponse("分片上传成功"));
        } catch (IOException e) {
            logger.error("分片上传失败: fileHash={}, chunk={}", fileHash, chunk, e);
            return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, "分片上传失败", e.getMessage());
        }
    }

    /**
     * 合并分片
     */
    @PostMapping("/merge")
    public ResponseEntity<?> mergeChunks(@RequestBody @NotNull(message = "请求参数不能为空") MergeRequest request) {
        try {
            logger.info("开始合并文件: fileHash={}, fileName={}, chunks={}", 
                    request.getFileHash(), request.getFileName(), request.getChunks());
            
            fileUploadService.mergeChunks(request.getFileHash(), request.getFileName(), request.getChunks());
            
            logger.info("文件合并成功: fileName={}", request.getFileName());
            return ResponseEntity.ok().body(buildSuccessResponse("文件合并成功"));
        } catch (IOException e) {
            logger.error("文件合并失败: fileHash={}, fileName={}", request.getFileHash(), request.getFileName(), e);
            return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, "文件合并失败", e.getMessage());
        }
    }

    /**
     * 构建成功响应
     */
    private Map<String, Object> buildSuccessResponse(String message) {
        Map<String, Object> response = new HashMap<>();
        response.put("code", 200);
        response.put("message", message);
        return response;
    }

    /**
     * 构建错误响应
     */
    private ResponseEntity<?> buildErrorResponse(HttpStatus status, String message, String details) {
        Map<String, Object> response = new HashMap<>();
        response.put("code", status.value());
        response.put("message", message);
        response.put("details", details);
        return ResponseEntity.status(status).body(response);
    }

    /**
     * 合并请求参数实体类
     */
    static class MergeRequest {
        @NotBlank(message = "文件哈希不能为空")
        private String fileHash;
        
        @NotBlank(message = "文件名不能为空")
        private String fileName;
        
        @NotNull(message = "分片数量不能为空")
        private Integer chunks;

        public String getFileHash() {
            return fileHash;
        }

        public void setFileHash(String fileHash) {
            this.fileHash = fileHash;
        }

        public String getFileName() {
            return fileName;
        }

        public void setFileName(String fileName) {
            this.fileName = fileName;
        }

        public Integer getChunks() {
            return chunks;
        }

        public void setChunks(Integer chunks) {
            this.chunks = chunks;
        }
    }
}